home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ue312src.zip / TIPC.C < prev    next >
Text File  |  1993-03-01  |  21KB  |  544 lines

  1. /*
  2.  * TIPC.C - TI Professional and compatible terminal driver for MicroEmacs.
  3.  *      This version by Ronald Lepine, Moderator - TI Conference
  4.  *      Byte Information Exchange.
  5.  *
  6.  *      BIX ID. ronlepine
  7.  *      Programers Room - Ronald Lepine (317) 742-5533  2400 baud
  8.  *      AT&T: (302) 836-8398
  9.  *      US Mail:
  10.  *          Ron Lepine
  11.  *          434 Shai Circle
  12.  *          Bear, DE   19701-3604
  13.  *
  14.  *      Adapted from code by Danial Lawrence for the IBM-PC.
  15.  *
  16.  *      February 1993, David G. Holm (email address: dgh@bix.com)
  17.  *               Updated to work with new TERM structure in 3.12 BETA 1.
  18.  *               Updated to work with Borland's C/C++ compilers.
  19.  *
  20.  * The routines in this file provide support for the TI-PC and other
  21.  * compatible terminals. It truely writes directly to the screen RAM to do
  22.  * screen output. It compiles into nothing if not a TI-PC driver.
  23.  *
  24.  * This driver for the TIPC is not the same one that Daniel Lawrence
  25.  * distributes.  He uses TI's DSRs for most functions as you can see by
  26.  * looking at the driver in ue311c.arc.  Dan's reverse video
  27.  * also does not work.  But do not blame him as I'm sure he does not
  28.  * have a TIPC to test Emacs on and he *is* supportting the TIPC.
  29.  * [Well, as you can see, it is the one I distribute now! - DAN]
  30.  * This driver uses direct writes to screen memory except for the message
  31.  * line like the IBM driver.  In fact I keep TI and IBM versions around by
  32.  * having my make file replace estruct.h with one that has a IBMPC defined
  33.  * only when I compile IBMPC.C and then switching back to estruct.h with
  34.  * TIPC defined. Its last step is of course linking in the correct object
  35.  * module for each exe.
  36.  *
  37.  * You can define any buffer to be reverse video by setting the
  38.  * foreground to "BLACK" and the background to any other color
  39.  * such as "cyan" to get Black on Cyan text.  There is no way to get
  40.  * colors such as 'White on blue' on the TIPC unless it has a
  41.  * least a 1-plane graphics card in it.  If it does have a graphics
  42.  * card installed the code to change overall background
  43.  * color is tied to the $palette variable with the same values as
  44.  * TI BASIC and the Tech Reference manual section 3.5.2 as well as
  45.  * being the #define for the color here without the enable attribute.
  46.  * The text mode forground/background code still works even when you
  47.  * use a $palette backgound giving you a wide range of what can be
  48.  * done even though some combinations don't really work too well.
  49.  *
  50.  * The only reason that there are any '#if color' directives is because of
  51.  * the need to maintain structure alignments.  This is because TI's mono
  52.  * is really 8 shades instead of 8 colors and all attributes  remain the
  53.  * same.  You can have color and mono attached at the same time and
  54.  * display on both without any program support or hardware changes.  So
  55.  * you should define color. It *will* make a difference in other areas of
  56.  * the MicroEmacs code. You also do not have to do anything special for
  57.  * the palette code because writing to a nonexistant graphics plane on a
  58.  * TI causes *no* ill effects (at least according to the tech manual).
  59.  *
  60.  * Note that if you recieve MicroEmacs for the TIPC compiled by me
  61.  * it is compiled/linked so that wildcard file names on the command
  62.  * line are automagicly expanded in case you want to work with several
  63.  * similarly named files.
  64.  *
  65.  * Changes to the other files to support the the TIPC MEMAPed
  66.  * version compiled under Zortech C/C++ 1.02 to 2.10 follow.
  67.  * BTW - The version I used is 2.18 but the earlier versions should
  68.  * still be similar since I have compiled previous versions under whatever
  69.  * was current at the time and even the previous ZTC version sometimes.
  70.  *
  71.  * [I simply added Ron's #ifdef changes to the master sources - Dan]
  72.  *
  73.  *     I once thought there were three ways to correct the problems with
  74.  * DSR writes to the *25th* line, I now know some don't work.
  75.  *     One was to check the start register before all screen writes. After
  76.  * some investigation and testing I found that the  6545A Start of screen
  77.  * registers are write only.  So there is not way to correct cursor
  78.  * postioning and line position whenever DOS has changed the register.
  79.  * Changing the start of screen pointer to offset 0 before screen writes
  80.  * also didn't solve the problem completely.  As soon as you touched a key
  81.  * after the error you ended up with the screen properly postioned, but
  82.  * you had the error message on the screen until that line was updated so
  83.  * you still ended up using a ^L to correct the screen.
  84.  *     Two is to capture critical errors (mlwrite and errors are the sources
  85.  * of DSR writes to the 25th line) and handle them myself (asm is
  86.  * only clean way) and now looks like the only way it is possible but must
  87.  * be used in conjuction with a modified method three too.
  88.  *     Three was change writes to the message line to direct screen writes
  89.  * and initialize the screen so that a critical error will write to the
  90.  * text portion of the screen where any repaints would clear it.  The same
  91.  * problems cropped up that did in number one where you needed to do a ^L
  92.  * to totally clean up the screen if the error occured while on the message
  93.  * line anyway so....
  94.  *     Therefore a combination of two and three is most likely the best
  95.  * way if it can be done since TI does not recommend mixing DSR and direct
  96.  * writes to screen (if  I could read the 6545 registers 0Bh and 0Ch I
  97.  * could manage it though).  This is because the DSR writes *can* change
  98.  * the screen start register. The problem with a 2+3 solution is mainly
  99.  * that the extra code to handle single character writes, directly
  100.  * controlling the cursor though the CRTC cursor registers, and the
  101.  * intercept/write/read error code handling bloats the code a bit and
  102.  * coding in anything but assembly language (which  then needs to be
  103.  * interfaced to each C compiler that might be in use) is the only reasonable
  104.  * way.  I just came came to the conclusion that it wasn't worth it since
  105.  * a ^L will clear things up anyway after the error is corrected.
  106.  *
  107.  * 12/29/89 -
  108.  *   Changed lnptr, sline, and scptr to char/char*'s because TI writes
  109.  *   only a character at a screen position and IBM a char + attribute.  TI's
  110.  *   attributes are kept up by the hardware except when changed. So we only
  111.  *   write a char at a time, not an int like the IBM code did.  This also
  112.  *   corrected a minor bug with the message line eeol's which is why I
  113.  *   looked at the driver code again.
  114.  *
  115.  * 12/30/89 -
  116.  *   added the capability of setting the background on machines with
  117.  *   graphics by setting the palette string with a number from 0 to 7.
  118.  *   you do this with ^XA $palette  (note small letters) and a value.
  119.  *   Values >= 8 will work since I do modulo division on the value
  120.  *   but results are the same as the color values in TI BASIC.  The
  121.  *   code, as always, works on all TI's but will not produce a change
  122.  *   on non-graphics equiped TI's.  This code also does not need a color
  123.  *   monitor to work since a TI doesn't know what kind of monitor is
  124.  *   attached and may even have color and mono attached at once.
  125.  *
  126.  *   With the code set up so you can still do reverse video on any TI
  127.  *   by defining BLACK and yellow (or any other background color) you
  128.  *   have a large variety of posible screen setups.  So experiment.
  129.  *
  130.  * 12/31/89 to 1/7/90 - experimented with various methods of eliminating
  131.  *   problems with mixed DSR/Direct_Memory writes.  Decided not to really
  132.  *   attempt a solution at this time.  Write Ron Lepine if you have
  133.  *   any feelings/suggestions on this problem, they are welcome.
  134.  *
  135.  * 1-9-90
  136.  *   3.10.c(Beta) New IBMPC reverse video code added to TIPC driver.
  137.  *
  138.  *   Addional changes to 3.10.c(beta) to get it to compile with Zortech C/C++
  139.  *     **** NOTE THESE CHANGES ARE NO LONGER NEEDED FOR ZTC 2.10 *****
  140.  *      isearch line 172/5, 191 - change lines to
  141.  *
  142.  *            if (kfunc == &forwsearch || kfunc == &forwhunt ||
  143.  *                kfunc == &backsearch || kfunc == &backhunt)
  144.  *            {
  145.  *                dir = (kfunc == &backsearch || kfunc == &backhunt)?
  146.  *                REVERSE: FORWARD;
  147.  *
  148.  * 5-26-90
  149.  *   Updated first part of this file to reflect 3.11beta line numbers
  150.  *   while compiling 3.11 beta under Zortech C/C++ 2.1.
  151.  *
  152.  * 6-04-91
  153.  *   Added last eight needed values to ctrans[] so standard emacs.rc file
  154.  *   now works.
  155.  */
  156.  
  157. #define termdef 1                       /* don't define "term" external */
  158.  
  159. #include        <stdio.h>
  160. #include        "estruct.h"
  161. #include        "eproto.h"
  162. #include        "edef.h"
  163. #include        "elang.h"
  164.  
  165. #if     TIPC
  166.  
  167. #define NROW    25                      /* Screen height.               */
  168. #define NCOL    80                      /* Screen width                 */
  169. #define MARGIN  8                       /* size of minimim margin and   */
  170. #define SCRSIZ  64                      /* scroll size for extended lines */
  171. #define NPAUSE  200                     /* # times thru update to pause */
  172. #define BEL     0x07                    /* BEL character.               */
  173. #define ESC     0x1B                    /* ESC character.               */
  174. #define SPACE   32                      /* space character              */
  175. #define SCADD       0xDE000000L         /* address of screen RAM        */
  176. #define ATTRADD     0xDE001800L         /* Address for attribute latch  */
  177. #define BLUE_PLANE  0xC0000000L         /* Address Blue graphics plane  */
  178. #define RED_PLANE   0xC8000000L         /* Address Red graphics plane   */
  179. #define GREEN_PLANE 0xD0000000L         /* Address Green graphics plane */
  180. #define CRTC_REG    0xDF810000L         /* 6545 CRT Controller access addr */
  181. #define CHAR_ENABLE     0x08            /* TI attribute to show char    */
  182. #define TI_REVERSE      0x10            /* TI attribute to reverse char */
  183. #define BLACK   0+CHAR_ENABLE           /* TI attribute for Black       */
  184. #define BLUE    1+CHAR_ENABLE           /* TI attribute for Blue        */
  185. #define RED     2+CHAR_ENABLE           /* TI attribute for Red         */
  186. #define MAGENTA 3+CHAR_ENABLE           /* TI attribute for Magenta     */
  187. #define GREEN   4+CHAR_ENABLE           /* TI attribute for Green       */
  188. #define CYAN    5+CHAR_ENABLE           /* TI attribute for Cyan        */
  189. #define YELLOW  6+CHAR_ENABLE           /* TI attribute for Yellow      */
  190. #define WHITE   7+CHAR_ENABLE           /* TI attribute for White       */
  191.  
  192.  
  193. PASCAL NEAR ttopen();               /* Forward references.          */
  194. PASCAL NEAR ttgetc();
  195. PASCAL NEAR ttputc();
  196. PASCAL NEAR ttflush();
  197. PASCAL NEAR ttclose();
  198. PASCAL NEAR timove();
  199. PASCAL NEAR tieeol();
  200. PASCAL NEAR tieeop();
  201. PASCAL NEAR tibeep();
  202. PASCAL NEAR tiopen();
  203. PASCAL NEAR tikopen();
  204. PASCAL NEAR tirev();
  205. PASCAL NEAR ticres();
  206. PASCAL NEAR ticlose();
  207. PASCAL NEAR tikclose();
  208. PASCAL NEAR tiputc();
  209. PASCAL NEAR tifcol();
  210. PASCAL NEAR tibcol();
  211. PASCAL NEAR scinit();
  212.  
  213. int     revflag = FALSE;        /* are we currently in rev video?       */
  214. int     cfcolor = -1;           /* current forground color              */
  215. int     cbcolor = -1;           /* current background color             */
  216. int     ctrans[] =              /* ANSI to TI color translation table   */
  217.         {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE,
  218.          BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE};
  219.  
  220. char *scptr[NROW];                      /* pointer to screen lines-8 bit on ti *
  221. char sline[NCOL];                       /* screen line image               */
  222.  
  223. #if  __TURBOC__
  224.  
  225. char far * scadd       = SCADD;        /* address of screen ram           */
  226. char far * attradd     = ATTRADD;      /* address of attribute latch      */
  227. char far * blue_plane  = BLUE_PLANE;   /* address of blue graphics plane  */
  228. char far * red_plane   = RED_PLANE;    /* address of red graphics plane   */
  229. char far * green_plane = GREEN_PLANE;  /* address of green graphics plane */
  230. char far * crtc_reg    = CRTC_REG;     /* 6545 CRT controller address     */
  231.  
  232. #else
  233.  
  234. long scadd       = SCADD;               /* address of screen ram           */
  235. long attradd     = ATTRADD;             /* address of attribute latch      */
  236. long blue_plane  = BLUE_PLANE;          /* address of blue graphics plane  */
  237. long red_plane   = RED_PLANE;           /* address of red graphics plane   */
  238. long green_plane = GREEN_PLANE;         /* address of green graphics plane */
  239. long crtc_reg    = CRTC_REG;            /* 6545 CRT controller address     */
  240.  
  241. #endif
  242.  
  243. /*
  244.  * Standard terminal interface dispatch table. Most of the fields point into
  245.  * "termio" code.
  246.  */
  247. TERM    term    = {
  248.         NROW-1,
  249.         NROW-1,
  250.         NCOL,
  251.         NCOL,
  252.         0,
  253.         0,
  254.         MARGIN,
  255.         SCRSIZ,
  256.         NPAUSE,
  257.         tiopen,
  258.         ticlose,
  259.         tikopen,
  260.         tikclose,
  261.         ttgetc,
  262.         tiputc,
  263.         ttflush,
  264.         timove,
  265.         tieeol,
  266.         tieeop,
  267.         tieeop,
  268.         tibeep,
  269.         tirev,
  270.         ticres
  271. #if COLOR
  272.         , tifcol,
  273.         tibcol
  274. #endif
  275. };
  276.  
  277. extern union REGS rg;
  278.  
  279.  
  280. PASCAL NEAR tifcol(color)           /* set the current output color */
  281.  
  282. int color;                          /* color to set */
  283. {
  284.     cfcolor = ctrans[color];
  285. }
  286.  
  287.  
  288. PASCAL NEAR tibcol(color)           /* set the current background color */
  289.                                     /* color to set */
  290. int color;
  291. {
  292.     cbcolor = ctrans[color];
  293. }
  294.  
  295.  
  296. PASCAL NEAR timove(row, col)
  297.  
  298. int row;
  299. int col;
  300. {
  301.     rg.h.ah = 2;            /* set cursor position function code */
  302.     rg.h.dh = col;
  303.     rg.h.dl = row;
  304.     int86(0x49, &rg, &rg);
  305. }
  306.  
  307.  
  308. PASCAL NEAR tieeol()        /* erase to the end of the line */
  309.  
  310. {
  311.     int i;                  /* loop variable                    */
  312.     char *lnptr;            /* pointer to the destination line  */
  313.     int ccol;               /* current column cursor lives      */
  314.     int crow;               /* current row  cursor lives        */
  315.  
  316.     /* find the current cursor position */
  317.     rg.h.ah = 3;            /* read cursor position function code */
  318.     int86(0x49, &rg, &rg);
  319.     ccol = rg.h.dh;         /* record current column */
  320.     crow = rg.h.dl;         /* and row */
  321.  
  322.     lnptr = &sline[0];      /* set things up */
  323.     for (i=0; i < term.t_ncol; i++)
  324.         *lnptr++ = SPACE;
  325.  
  326.     _fmemset(attradd, cfcolor, 1);                /* write current attrs to latc
  327.     movmem(&sline[0], scptr[crow]+ccol, term.t_ncol-ccol);
  328.  
  329. }
  330.  
  331.  
  332. PASCAL NEAR tiputc(ch)      /* put a character at the current position */
  333.                             /* in the current colors */
  334. int ch;
  335. {
  336.     _fmemset(attradd, cfcolor, 1);    /* write current attrs to latch */
  337.     rg.h.ah = 0x0E;                 /* write char to screen with DSR */
  338.     rg.h.al = ch;
  339.     int86(0x49, &rg, &rg);
  340. }
  341.  
  342.  
  343. PASCAL NEAR tieeop()        /* Actually a clear screen */
  344.  
  345. {
  346.     rg.h.ah = 0x13;         /* Clear Text Screen, Home Cursor and */
  347.     int86(0x49, &rg, &rg);  /* Set screen start register to 0     */
  348. }
  349.  
  350.  
  351. PASCAL NEAR tirev(state)    /* change reverse video state */
  352.  
  353. int state;          /* TRUE = reverse, FALSE = normal */
  354. {
  355.     revflag = state;
  356. }
  357.  
  358.  
  359. PASCAL NEAR ticres()    /* Change screen resolution. Should we add the  */
  360.                         /* the 720x350 mode besides the normal 720x300  */
  361.                         /* mode for those who can handle it?  It really */
  362.                         /* gains us nothing since we don't gain lines   */
  363.                         /* and the code works when started in that res. */
  364.                         /* Let me (Ron Lepine) know what you think      */
  365. {
  366.     return(TRUE);
  367. }
  368.  
  369.  
  370. PASCAL NEAR tibeep()
  371.  
  372. {
  373.     bdos(6, BEL, 0);
  374. }
  375.  
  376.  
  377. PASCAL NEAR tiopen()
  378.  
  379. {
  380.     strcpy(sres, "NORMAL");
  381.     revexist = TRUE;
  382.     revflag = FALSE;
  383.     scinit();
  384.     ttopen();
  385. }
  386.  
  387.  
  388. PASCAL NEAR tikopen()
  389.  
  390. {
  391.     /* Does nothing */
  392. }
  393.  
  394.  
  395. PASCAL NEAR ticlose()
  396.  
  397. {
  398.     _fmemset(attradd, WHITE, 1);  /* write normal attrbute to latch      */
  399.                     /* Makes sure we return with a normal color        */
  400.                     /* and not reverse video or such.  Attribute       */
  401.                     /* Latch will otherwise hold last color and        */
  402.                     /* attributes it wrote to the screen, which in     */
  403.                     /* some cases is reverse video.                    */
  404. }
  405.  
  406.  
  407. PASCAL NEAR tikclose()
  408.  
  409. {
  410.     _fmemset(attradd, WHITE, 1);  /* write normal attrbute to latch         */
  411.                     /* Dan doesn't close the the terminal when shelling   */
  412.                     /* This ensures the shell starts with a normal color  */
  413.                     /* the same way ticlose does without changing         */
  414.                     /* *any* other source file.  The only real reason we  */
  415.                     /* place it here is to change as few files as posible */
  416. }
  417.  
  418.  
  419. PASCAL NEAR scinit()    /* initialize the screen head pointers to */
  420.                         /* logical screen */
  421. {
  422.     union {
  423.         long laddr;     /* long form of address */
  424.         char *paddr;    /* pointer form of address */
  425.     } addr;
  426.  
  427.     char i;
  428.  
  429.     tieeop();           /* set logical = physical start of screen   */
  430.         /* initialize The screen pointer array */
  431.     for (i = 0; i < NROW; i++) {
  432.         addr.laddr = scadd + (long)(NCOL * i);
  433.         scptr[i] = addr.paddr;
  434.     }
  435. }
  436.  
  437.  
  438. PASCAL NEAR scwrite(int row, char *outstr, int forg, int bacg, int revleft, int
  439. /* write a line out */
  440. {
  441.     char    *lnptr;         /* Pointer to the destination line */
  442.     char    i;
  443.  
  444.     /* Write the attribute byte to latch and setup the screen pointer      */
  445.     /* If forg == 0 then you can change the back ground to color.  TI      */
  446.     /* won't let you use two colors for forground and background unless    */
  447.     /* you have graphics and set the graphics color to your background     */
  448.     /* This is enabled in this driver though the $palette variable         */
  449.  
  450.     if ((forg != 0) & (!revflag)) {
  451.         forg = ctrans[forg];
  452.         _fmemset(attradd, forg, 1);
  453.     }else if ((forg != 0) & (revflag)) {
  454.         forg = ctrans[forg] + TI_REVERSE;
  455.         _fmemset(attradd, forg, 1);
  456.     }else{
  457.         bacg = ctrans[bacg] + TI_REVERSE;
  458.         _fmemset(attradd, bacg, 1);
  459.     }
  460.     lnptr = &sline[0];
  461.     for (i=0; i<term.t_ncol; i++)
  462.         *lnptr++ = outstr[i];
  463.     /* and send the string out */
  464.     movmem(&sline[0], scptr[row], term.t_ncol);
  465. }
  466.  
  467.  
  468. PASCAL NEAR spal(palette)      /* change palette string */
  469.  
  470. char *palette;
  471. {
  472.     /* Turns on a graphics plane if it is installed         */
  473.     /* Set value of $palette works the same as in TI BASIC  */
  474.     /* and the Technical Reference manual section 3.5.2     */
  475.     /* ie. Set $palette to 7 for a white background or to   */
  476.     /* 1 for a blue background.                             */
  477.     /* Causes no problems when graphics are not installed   */
  478.     /* so there is no reason to check for the number of     */
  479.     /* graphics planes installed.                           */
  480.  
  481.     switch ((atoi(palette) % 8)) {
  482.         case 0:
  483.             _fmemset(blue_plane,   0,  0x7fff);
  484.             _fmemset(red_plane,    0,  0x7fff);
  485.             _fmemset(green_plane,  0,  0x7fff);
  486.             break;
  487.         case 1:
  488.             _fmemset(blue_plane,   0xff,  0x7fff);
  489.             _fmemset(red_plane,    0,     0x7fff);
  490.             _fmemset(green_plane,  0,     0x7fff);
  491.             break;
  492.         case 2:
  493.             _fmemset(blue_plane,   0,    0x7fff);
  494.             _fmemset(red_plane,    0xff, 0x7fff);
  495.             _fmemset(green_plane,  0,    0x7fff);
  496.             break;
  497.         case 3:
  498.             _fmemset(blue_plane,   0xff, 0x7fff);
  499.             _fmemset(red_plane,    0xff, 0x7fff);
  500.             _fmemset(green_plane,  0,    0x7fff);
  501.             break;
  502.         case 4:
  503.             _fmemset(blue_plane,   0,    0x7fff);
  504.             _fmemset(red_plane,    0,    0x7fff);
  505.             _fmemset(green_plane,  0xff, 0x7fff);
  506.             break;
  507.         case 5:
  508.             _fmemset(blue_plane,   0xff, 0x7fff);
  509.             _fmemset(red_plane,    0,    0x7fff);
  510.             _fmemset(green_plane,  0xff, 0x7fff);
  511.             break;
  512.         case 6:
  513.             _fmemset(blue_plane,   0,    0x7fff);
  514.             _fmemset(red_plane,    0xff, 0x7fff);
  515.             _fmemset(green_plane,  0xff, 0x7fff);
  516.             break;
  517.         case 7:
  518.             _fmemset(blue_plane,   0xff, 0x7fff);
  519.             _fmemset(red_plane,    0xff, 0x7fff);
  520.             _fmemset(green_plane,  0xff, 0x7fff);
  521.             break;
  522.     }
  523. }
  524.  
  525.  
  526. #if     FLABEL
  527. PASCAL NEAR fnclabel(f, n)      /* label a function key */
  528.  
  529. int f,n;        /* default flag, numeric argument [unused] */
  530.  
  531. {
  532.         /* on machines with no function keys...don't bother */
  533.         /* TI/IBM function keys are handled in other code   */
  534.         return(TRUE);
  535. }
  536. #endif
  537.  
  538.  
  539. #else
  540. tihello()
  541. {
  542. }
  543. #endif
  544.